package com.sensePlusVR.manager;

import com.alibaba.fastjson.JSON;
import com.sensePlusVR.application.VRApplication;
import com.sensePlusVR.bean.CollectionItem;
import com.sensePlusVR.bean.GameItem;
import com.sensePlusVR.bean.GamePageItem;
import com.sensePlusVR.bean.GameSearchDto;
import com.sensePlusVR.bean.GameSearchReqV4;
import com.sensePlusVR.main.R;
import com.sensePlusVR.net.NetCallBack;
import com.sensePlusVR.net.NetRequestManager;
import com.sensePlusVR.net.RequestUtils;
import com.sensePlusVR.utils.Constant;
import com.sensePlusVR.utils.ConstantURL;
import com.sensePlusVR.utils.MyLog;
import com.sensePlusVR.utils.MySharedPreferences;
import com.sensePlusVR.utils.MyToast;
import com.sensePlusVR.utils.PageUtil;

import org.apache.http.Header;
import org.apache.http.entity.ByteArrayEntity;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("deprecation")
public class GameItemManager extends BaseManager {

	private static final String TAG = GameItemManager.class.getSimpleName();
	
	public static final int EventGameItemAllGot = 0;
	public static final int EventGameItemMoreGot = 1;
	public static final int EventGameItemIdsGot = 2;
	public static final int EventGameItemChanged = 3;
	public static final int EventGameItemActorName = 4;
	public static final int EventGameItemRefreshGot = 5;

	private static GameItemManager INSTANTS;
	private static Object lock;
	private int pageSize = PageUtil.GAME_PAGE_SIZE;
	private int currentPage = 0;// currentPage 传0则返回数据为1，即永远返回下一页的数据
	//private int networkItems = 0;
	private int totalItems = 0;
	private DownloadTask taskall, taskByName;
	
	private List<GameItem> collectionList = new ArrayList<GameItem>();
		
	public void resetDbIndex(){
		currentPage = 0;
		localCurrPage = 0;
		totalItems = 0;
		//networkItems = 0;
	}
	
	static public GameItemManager getInstants() {

		if (INSTANTS == null) {
			INSTANTS = new GameItemManager();
			lock = new Object();
		}
		return INSTANTS;
	}

	public List<GameItem> getGameListByIds(List<Integer> ids) {
		List<Integer> newIds = new ArrayList<Integer>();
		for(Integer id : ids){
			GameItem gItem = GameItem.getGameById(id);
			if(gItem != null && GameItem.isRealGame(gItem)){
				newIds.add(id);
			}
		}
		List<GameItem> list = GameItem.getGameListByIds(newIds);
		if (list == null || newIds.size() < ids.size()) {
			updateCollectGameItem(true, ids,true);
		}else{
			callEventListener(EventGameItemIdsGot, list);
		}
		return list;
	}

	private int currentPageClc = 0;
	
	private void updateCollectGameItem(boolean isLoadCollect,List<Integer> ids,boolean isFirst){
		MyLog.d(TAG, "updateCollectGameItem currentPageClc : " + currentPageClc + " ids : " + ids);
		if(isFirst){
			collectionList.clear();
			currentPageClc = 0;
		}else{
			currentPageClc++;
		}
		synchronized (lock) {
			DownloadTask taskColect = new DownloadTask(isLoadCollect, ids);
			taskColect.start();
		}
	}
	

	public List<GameItem> getGameListByActorName(String name, boolean update){
		List<GameItem> list = GameItem.getGameListByActorName(name);
		if (list== null || list.isEmpty() || update){
			synchronized (lock) {
				if (taskByName == null) {
					taskByName = new DownloadTask(name);
					taskByName.start();
				}
			}
		}
		return list;
	}
	
	public List<GameItem> getGameListByActorName(String name, boolean update,boolean desc){
		List<GameItem> list = GameItem.getGameListByActorName(name,desc);
		if (list== null || list.isEmpty() || update){
			synchronized (lock) {
				if (taskByName == null) {
					taskByName = new DownloadTask(name);
					taskByName.start();
				}
			}
		}
		return list;
	}
	
	public long getGameLocalCount(){
		return GameItem.getGameCount();
	}
	
	public List<GameItem> getGameListSort(boolean sort, boolean update,boolean isRefresh) {
		List<GameItem> list = GameItem.getGameListSort(sort, pageSize, totalItems);
		MyLog.d(TAG, "totalItems start : " + totalItems);
		if (list == null || update || list.isEmpty()) {
			// do find on network
			MyLog.e(TAG, "updateGameItem...");
			if(isRefresh && currentPage > 0){
				MyLog.d(TAG, "currentPage --");
				currentPage -= 1;
			}
			updateGameItem(isRefresh);
		}
		if (list != null){
			MyLog.d(TAG, "updateGameItem list size : " + list.size());
			if(/*!isRefresh && */list.size() == pageSize) {
				MyLog.d(TAG, "currentPage ++");
					currentPage += 1;
			}
			totalItems += list.size();
			MyLog.d(TAG, "return list size : " + list.size());
		}
		MyLog.d(TAG, "currentPage : " + currentPage + " totalItems : " + totalItems);
		return list;
	}
	
	
	private void updateGameItem(boolean isRefresh) {
		synchronized (lock) {
			if (taskall == null)
				taskall = new DownloadTask(isRefresh);
			else {
				MyLog.e(TAG, "GameItem update is running....");
				return;
			}
		}
		taskall.start();
	}
	

	public class DownloadTask {
		private String actorName;
		private boolean isRefresh;
		private boolean isLoadCollect;
		private List<Integer> ids;
		public DownloadTask(boolean isRefresh){
			this.isRefresh = isRefresh;
		}
		public DownloadTask(String actorName){
			this.actorName = actorName;
		}
		
		public DownloadTask(boolean isLoadCollect,List<Integer> ids){
			this.isLoadCollect = isLoadCollect;
			this.ids = ids;
		}
		
		private List<GameItem> updateDB(GamePageItem gamePageItem) {

			List<GameItem> newList = new ArrayList<GameItem>();
			if (gamePageItem != null) {
				List<GameItem> giList = gamePageItem.getListMI();
				if (giList != null && giList.size() > 0) {
					for (int i = 0; i < giList.size(); i++) {
						GameItem gameItem = giList.get(i);
						MyLog.e(TAG, "gameItem="+gameItem.getId()+"  is colloection="+gameItem.getColloctoned());
						MyLog.e(TAG, "gameURl="+gameItem.getGameurl());
						if (GameItem.getGameById(gameItem.getId()) == null)
						{
							newList.add(gameItem);
						}
					}
					MyLog.d(TAG, "updateDB save gamelist...");
					GameItem.saveOrUpdate(giList);// 保存本地数据库
				}
			}
			return newList;
		}
		
		private List<GameItem> getAllPageGameList(GamePageItem gamePageItem){
			
			List<GameItem> allPageList = new ArrayList<GameItem>();
			if (gamePageItem != null) {
				List<GameItem> giList = gamePageItem.getListMI();
				if (giList != null && giList.size() > 0) {
					for (int i = 0; i < giList.size(); i++) {
						GameItem gameItem = giList.get(i);
						MyLog.e(TAG, "gameItem="+gameItem.getId()+"  is colloection="+gameItem.getColloctoned());
						MyLog.e(TAG, "gameURl="+gameItem.getGameurl());
						allPageList.add(gameItem);
					}
					MyLog.d(TAG, "getAllPageGameList save gamelist...");
					GameItem.saveOrUpdate(giList);// 保存本地数据库
				}
			}
			return allPageList;
			
		} 

		public void start() {
			MyLog.d(TAG, "getGameListFromNet...currentPage : " + currentPage);
			GameSearchReqV4 gsrvBase = new GameSearchReqV4();
			List<GameSearchDto> listAnd = new ArrayList<GameSearchDto>();
//			List<GameSearchDto> listOr = new ArrayList<GameSearchDto>();
			
			//addList
			if (actorName != null && !actorName.equals("")){
				gsrvBase.setPageSize(0);
				gsrvBase.setCurrentPage(0);
				gsrvBase.setOrderBy("createtime:DESC");
				MyLog.d(TAG, "actor name : " + actorName);
				GameSearchDto conditionByActorName = new GameSearchDto();
				conditionByActorName.setKey("actors");
				conditionByActorName.setValue(actorName);
				conditionByActorName.setOp("eq");
				listAnd.add(conditionByActorName);
			}else if(isLoadCollect && ids!=null){
				gsrvBase.setPageSize(pageSize);
				gsrvBase.setCurrentPage(currentPageClc);
				gsrvBase.setOrderBy("createtime:DESC");
			}else{
				gsrvBase.setPageSize(pageSize);
				gsrvBase.setCurrentPage(currentPage);
				gsrvBase.setOrderBy("createtime:DESC");
			}
			
			GameSearchDto conditionTypeRear = new GameSearchDto();
			conditionTypeRear.setKey("type");
			conditionTypeRear.setValue(Constant.TYPE_REAL);
			conditionTypeRear.setOp("eq");
			listAnd.add(conditionTypeRear);
			
			GameSearchDto  conditionTypeVersion = new GameSearchDto();
			conditionTypeVersion.setKey("version");
			conditionTypeVersion.setValue(Constant.TYPE_EQ_V6);
			conditionTypeVersion.setOp("eq");
			listAnd.add(conditionTypeVersion);

//q			GameSearchDto  conditionTypeReal = new GameSearchDto();
//			conditionTypeReal.setKey("type");
//			conditionTypeReal.setValue(Constant.TYPE_LIKEREAL);
//			conditionTypeReal.setOp("eq");
//			listOr.add(conditionTypeReal);	
			
			
			//orList
//			List<GameSearchDto> listOr = new ArrayList<GameSearchDto>();
//			GameSearchDto  conditionTypeLikeRear = new GameSearchDto();
//			conditionTypeLikeRear.setKey("type");
//			conditionTypeLikeRear.setValue(Constant.TYPE_LIKEREAL);
//			conditionTypeLikeRear.setOp("eq");
//			listOr.add(conditionTypeLikeRear);
			
			gsrvBase.setAndList(listAnd);
//			gsrvBase.setOrList(listOr);
			//gsrvBase.setOrList(listOr);
			
			String json = JSON.toJSONString(gsrvBase);

			MyLog.d(TAG, "json : " + json.toString());
			
			String token = MySharedPreferences.getString2(VRApplication.getAppContext(),MySharedPreferences.NAME_NOT_CLEAR, Constant.LOGIN_SUCCESS_TOKEN);
			MyLog.d(TAG, "gameUrl getGameListFromNet : " + ConstantURL.GAME_LIST);
			RequestUtils.clientToken.addHeader(Constant.STR_X_AUTH_TOKEN,token);
			
			RequestUtils.clientTokenPost(VRApplication.getAppContext(), ConstantURL.GAME_LIST,
					new ByteArrayEntity(json.getBytes()), Constant.STR_APPLICATION_JSON, new NetCallBack() {

						@Override
						public void onMySuccess(int statusCode, Header[] aheader, JSONObject jsonobject) {
							MyLog.d(TAG, "getGameListFromNet onMySuccess statusCode : " + statusCode);
							MyLog.d(TAG, "getGameListFromNet onMySuccess jsonobject : " + jsonobject.toString());
							if (statusCode == 200) {
								GamePageItem gamePageItem = JSON.parseObject(jsonobject.toString(), GamePageItem.class);
								// gamePageItem.get
								if (gamePageItem != null) {
									List<GameItem> newlist = updateDB(gamePageItem);
									MyLog.d(TAG, "newList size : " + newlist.size());
									
									MyLog.d(TAG, "isLoadCollect : " + isLoadCollect);
									
									//NotifyUser(gamePageItem.getListMI(), gamePageItem.getListMI().size());
									if (actorName != null){
										callEventListener(EventGameItemActorName, newlist);
									}else if(isLoadCollect){
										newlist = getAllPageGameList(gamePageItem);
										MyLog.d(TAG, "isLoadCollect newlist size : " + newlist.size());
										if(newlist != null && newlist.size() > 0){
											for(GameItem gameItem:newlist){
												int currentId = gameItem.getId();
												MyLog.d(TAG, "currentId : " + currentId);
												for(Integer id :  ids){
													if(id == currentId){
														CollectionItem.addCollection(gameItem);
														collectionList.add(gameItem);
														ids.remove(id);
														MyLog.d(TAG, "ids remove currentId : " + currentId);
														break;
													}else{
														MyLog.d(TAG, "ids not remove currentId : " + currentId);
													}
												}
											}
											MyLog.d(TAG, "ids size : " + ids.size());
											if(ids.size() > 0){
												updateCollectGameItem(true, ids,false);
											}else{
												callEventListener(EventGameItemIdsGot, collectionList);
											}
										}else{
											currentPageClc = 0;
											callEventListener(EventGameItemIdsGot, collectionList);
										}
									}else{
										if (!gamePageItem.getListMI().isEmpty()) {
											MyLog.d(TAG, "currentPage11 : " + currentPage + " totalItems : " + totalItems);
											if (currentPage == 0 /*&& networkItems == 0*/ && totalItems == 0){
												callEventListener(EventGameItemAllGot, gamePageItem.getListMI());
											}else{
												if(isRefresh){
													callEventListener(EventGameItemRefreshGot, newlist);
												}else{
													callEventListener(EventGameItemMoreGot, newlist);
												}
												
											}
											//networkItems += gamePageItem.getListMI().size();
											totalItems += newlist.size();
										}
										if (gamePageItem.getListMI().size() == pageSize){
											currentPage += 1;//gamePageItem.getCurrentPage();
										}
									}
									
									MyLog.d(TAG, "currentPage22 : " + currentPage + " totalItems : " + totalItems);
								} else {
									MyToast.showMessage(VRApplication.getAppContext(), R.string.msg_success_nodata);
								}
							}
							synchronized (lock) {
								if (actorName == null){
									taskall = null;
								}else{
									taskByName = null;
								}
							}
						}
						
						@Override
						public void onMyFailure(int statusCode, Header[] headers,
								Throwable throwable, JSONArray errorResponse) {
							super.onMyFailure(statusCode, headers, throwable, errorResponse);
							MyLog.e(TAG, "getGameListFromNet onMyFailure statusCode : "
									+ statusCode);
							if(errorResponse == null){
								MyLog.e(TAG, "getGameListFromNet onMyFailure errorResponse == null");
								return;
							}
							MyLog.e(TAG, "getGameListFromNet onMyFailure errorResponse : "
									+ errorResponse.toString());
						}

						@Override
						public void onMyFailure(int statusCode, Header[] headers, Throwable throwable,
								JSONObject errorResponse) {
							super.onMyFailure(statusCode, headers, throwable, errorResponse);
							synchronized (lock) {
								if (actorName == null){
									taskall = null;
								}else{
									taskByName = null;
								}
							}
							NetRequestManager.isCommonErr(statusCode, errorResponse, VRApplication.getAppContext());
							
							if(throwable != null){
								MyLog.d(TAG, "throwable : " + throwable.getMessage());
							}
							
							MyLog.e(TAG, "onMyFailure statusCode : " + statusCode);
			    	        if(statusCode == 0 || errorResponse == null){
			    	        	MyLog.e(TAG, "onMyFailure errorJsonobject == null");
			    	        	return ;
			    	        }
			    	        MyLog.e(TAG, "error errorResponse : " + errorResponse.toString());
						}
					});
		}

	}

}
